﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Windows.Input;
using System;
using System.Windows.Media;
using System.Windows.Shapes;
using System.ComponentModel;

namespace WickedFlame.VecDraw.Base.Controls
{
	[TemplatePart(Name = "PART_SwatchCanvas", Type = typeof(Canvas)), TemplatePart(Name = "PART_SelectionPoint", Type = typeof(Ellipse))]
	public class ColorSwatch : System.Windows.Controls.Control
	{
		Canvas swatchcanvas;
		Ellipse selectionpoint;

		static ColorSwatch()
        {
			DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorSwatch), new FrameworkPropertyMetadata(typeof(ColorSwatch)));
        }

		public override void OnApplyTemplate()
		{
			if (swatchcanvas != null)
			{
				swatchcanvas.MouseLeftButtonUp -= new System.Windows.Input.MouseButtonEventHandler(Swatch_MouseLeftButtonUp);
				swatchcanvas = null;
			}

			base.OnApplyTemplate();

			swatchcanvas = GetTemplateChild("PART_SwatchCanvas") as Canvas;
			if (swatchcanvas != null)
				swatchcanvas.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(Swatch_MouseLeftButtonUp);

			if (selectionpoint == null)
				selectionpoint = GetTemplateChild("PART_SelectionPoint") as Ellipse;
		}

		void Swatch_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
		{
			try
			{
				var ColorImage = ((Image)SwatchImage).Source as BitmapSource;

				CroppedBitmap cb = new CroppedBitmap(ColorImage,
					new Int32Rect((int)Mouse.GetPosition(swatchcanvas).X,
						(int)Mouse.GetPosition(swatchcanvas).Y, 1, 1));

				byte[] pixels = new byte[4];

				try
				{
					cb.CopyPixels(pixels, 4, 0);
				}
				catch { }

				SelectedColor = Color.FromArgb((byte)255, pixels[2], pixels[1], pixels[0]);


				selectionpoint.SetValue(System.Windows.Controls.Canvas.LeftProperty, (double)(Mouse.GetPosition(swatchcanvas).X - 2.5));
				selectionpoint.SetValue(System.Windows.Controls.Canvas.TopProperty, (double)(Mouse.GetPosition(swatchcanvas).Y - 2.5));
				//swatchcanvas.InvalidateVisual();
			}
			catch (Exception ex)
			{
				System.Diagnostics.Debug.Write(ex.Message);
			}
		}

		#region Dependencie Properties

		[Bindable(true)]
		public Color SelectedColor
		{
			get
			{
				return (Color)GetValue(SelectedColorProperty);
			}
			set
			{
				SetValue(SelectedColorProperty, value);
			}
		}

		public static readonly DependencyProperty SelectedColorProperty =
			DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorSwatch),
			new FrameworkPropertyMetadata(Colors.Transparent, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
			new PropertyChangedCallback(OnSelectedValueChanged)));

		protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
		{
			base.OnPropertyChanged(e);
			DependencyProperty prop = e.Property;
			if (prop == ColorSwatch.SelectedColorProperty)
			{
				this.SelectedColor = (Color)e.NewValue;
			}
		}

		private static void OnSelectedValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
		}

		[Bindable(true)]
		public object SwatchImage
		{
			get
			{
				return (object)GetValue(SwatchImageProperty);
			}
			set
			{
				SetValue(SwatchImageProperty, value);
			}
		}

		public static readonly DependencyProperty SwatchImageProperty =
			DependencyProperty.Register("SwatchImage", typeof(object), typeof(ColorSwatch), new FrameworkPropertyMetadata(null, new CoerceValueCallback(OnCoerce_Icon)));

		private static object OnCoerce_Icon(DependencyObject o, object value)
		{
			if (value is string)
			{
				Uri iconUri;
				// try to resolve given value as an absolute URI
				if (Uri.TryCreate(value as String, UriKind.RelativeOrAbsolute, out iconUri))
				{
					ImageSource img = new BitmapImage(iconUri);
					if (null != img)
					{
						Image icon = (o as ColorSwatch).SwatchImage as Image;
						if (null == icon)
							icon = new Image();

						icon.Source = img;
						icon.Stretch = Stretch.None;
						icon.SnapsToDevicePixels = true;

						return icon;
					}
				}
			}
			return value;
		}


		#endregion
	}
}
